#pragma once
#include "../Ode.h"

namespace Skill
{
	namespace Ode
	{
		public ref class DVector3 : DIUnmanagedPointer
		{
			INTERNAL_CLASS_DECLARATION(DVector3,dReal);
		public:
			UNMANAGEDPOINTER_DECLARATION();

			DVector3()
			{
				_SetPointer(new dVector3(),true);
			}
			DVector3(dReal x,dReal y,dReal z)
			{
				_SetPointer(new dVector3(),true);
				_This[0] = x;
				_This[1] = y;
				_This[2] = z;
			}
			DVector3(DVector3^ other)
			{
				_SetPointer(new dVector3(),true);
				_This[0] = other->_This[0];
				_This[1] = other->_This[1];
				_This[2] = other->_This[2];
			}

			void Set(dReal x,dReal y,dReal z)
			{				
				_This[0] = x;
				_This[1] = y;
				_This[2] = z;
			}

			property dReal default[int]
			{
				dReal get(int index);
				void set(int index,dReal value);
			}

			VALUE_PROP_DECLARATION_GETSET(dReal,X);
			VALUE_PROP_DECLARATION_GETSET(dReal,Y);
			VALUE_PROP_DECLARATION_GETSET(dReal,Z);

			///<summary> set a vector to all zeros </summary>
			void SetZero();

			///<summary> set a vector to specific value </summary>
			void SetValue(dReal value);

			///<summary> get the dot product of two vectors. </summary> 
			dReal Dot(DVector3^ a,DVector3^ b);

			///<summary> in matlab syntax: a(1:n) = a(1:n) .* d(1:n) </summary> 
			void Scale(DVector3^ d);

			virtual String^ ToString() override
			{
				return String::Format("X: {0} Y: {1} Z: {2}",_This[0],_This[1],_This[2]);
			}
		};
	}
}